<?php

namespace maotool\util;

use maotool\object\ObjUtil;
use maotool\object\ReflectionUtil;
use maotool\object\StrUtil;

/**
 * 数组操作
 */
class ArrayUtil
{

    /**
     * 数组转int类型
     * @param $list
     * @return array
     */
    public static function toInt($list)
    {
        $new = [];
        foreach ($list as $item) {
            $new[] = intval($item);
        }
        return $new;
    }

    /**
     * 数组转string类型
     * @param $list
     * @return array
     */
    public static function toStr($list)
    {
        $new = [];
        foreach ($list as $item) {
            $new[] = strval($item);
        }
        return $new;
    }

    /**
     * 删除数组多余字段
     * @param $list
     * @param $selects
     * @return mixed
     */
    public static function select($list, $selects = [])
    {
        foreach ($list as &$item) {
            $newItem = [];
            foreach ($selects as $select) {
                $newItem[$select] = $item[$select];
            }
            $item = $newItem;
        }
        return $list;
    }

    /**
     * 数组去重
     * @param $list $ 数据
     * @param $key $ 针对二维数组去重
     * @return array 去重后数据
     */
    public static function distinct($list, $key = null)
    {
        $newList = [];
        if (is_null($key)) {
            foreach ($list as $item) {
                $newList[md5("id:" . json_encode($item))] = $item;
            }
        } else {
            foreach ($list as $item) {
                if (is_array($item)) {
                    $newList[md5("id:" . json_encode($item[$key]))] = $item;
                } else if (is_object($item)) {
                    $newList[md5("id:" . json_encode(ReflectionUtil::getProperty($item, $key)))] = $item;
                }
            }
        }
        return array_values($newList);
    }

    /**
     * 数组排序
     * @param $list
     * @param $flags
     * @param $key
     * @return array|mixed
     */
    public static function sort($list, $flags = SORT_ASC, $key = null)
    {
        if (is_null($key)) {
            sort($list, $flags);
        } else {
            $columns = array_column($list, $key);
            array_multisort($columns, $flags, $list);
        }
        return $list;
    }

    /**
     * 拆分数组
     * @param $list
     * @param $size
     * @return array
     */
    public static function split($list, $size)
    {
        return array_chunk($list, $size);
    }

    /**
     * 转为字符串
     * @param $list
     * @param $separator
     * @return string
     */
    public static function join($list, $separator)
    {
        return implode($separator, $list);
    }

    /**
     * 字符串转数组
     * @param $str
     * @param $separator
     * @return false|string[]
     */
    public static function explode($str, $separator)
    {
        return explode($separator, $str);
    }

    /**
     * 查找包含字段值的数据
     * @param $list
     * @param $key
     * @param $value
     * @return mixed|null
     */
    public static function findOne($list, $key, $value)
    {
        foreach ($list as $item) {
            if ($item[$key] == $value) {
                return $item;
            }
        }
        return null;
    }

    /**
     * 筛选数据
     * @param $list
     * @param $func
     * @param ...$ages
     * @return mixed|null
     */
    public static function filterOne($list, $func, ...$ages)
    {
        foreach ($list as $item) {
            if ($func($item, ...$ages)) {
                return $item;
            }
        }
        return null;
    }

    /**
     * 合并数组
     * @param ...$list
     * @return array
     */
    public static function merge(...$list)
    {
        $newList = [];
        foreach ($list as $item) {
            if (is_array($item)) {
                foreach ($item as $it) {
                    $newList[] = $it;
                }
            }
        }
        return $newList;
    }

    /**
     * 是否是数组
     * @param $list
     * @return bool
     */
    public static function isArray($list)
    {
        return is_array($list);
    }

    /**
     * 是否不是数组
     * @param $list
     * @return bool
     */
    public static function isNotArray($list)
    {
        return !ArrayUtil::isArray($list);
    }

    /**
     * 数组key是否存在
     * @param $key
     * @param $list
     * @return bool
     */
    public static function keyExists($key, $list)
    {
        if (is_array($list) && count($list) && ObjUtil::isNotNull($key)) {
            foreach ($list as $i => $v) {
                if (ObjUtil::equals($key, $i)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 数组key是否不存在
     * @param $key
     * @param $list
     * @return bool
     */
    public static function keyNotExists($key, $list)
    {
        return !self::keyExists($key, $list);
    }

    /**
     * 数组值是否存在
     * @param $value
     * @param $list
     * @param $key
     * @return bool
     */
    public static function valueExists($value, $list, $key = null)
    {
        if (is_array($list) && count($list)) {
            foreach ($list as $item) {
                if (ObjUtil::isNull($key)) {
                    if (ObjUtil::equals($item, $value)) {
                        return true;
                    }
                } else {
                    if (isset($item[$key])) {
                        if (ObjUtil::equals($item[$key], $value)) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    /**
     * 数组值是否不存在
     * @param $value
     * @param $list
     * @param $key
     * @return bool
     */
    public static function valueNotExists($value, $list, $key = null)
    {
        return !self::valueExists($value, $list, $key);
    }

    /**
     * 转化对象为数组
     * @param $obj
     * @return mixed
     */
    public static function parserObj($obj)
    {
        return json_decode(json_encode($obj), true);
    }

    /**
     * 转化Map键值对为数组
     * @param $list
     * @return array
     */
    public static function parserListMap($list)
    {
        $array = [];
        foreach ($list as $key => $value) {
            $array = $value;
        }
        return $array;
    }

    /**
     * 数组转换为Map键值对
     * @return array
     */
    public static function toListMap($list, $key)
    {
        $map = [];
        foreach ($list as $item) {
            $map[$item[$key]] = $item;
        }
        return $map;
    }

    /**
     * 获取两个数组之间的差集
     * @param $array1
     * @param $array2
     * @param $key
     * @return array
     */
    public static function diff($array1, $array2, $key = null)
    {
        $newArray1 = [];
        $newArray2 = [];
        if (is_null($key)) {
            foreach ($array1 as $item) {
                $newArray1[] = md5("id:" . json_encode($item));
            }
            foreach ($array2 as $item) {
                $newArray2[] = md5("id:" . json_encode($item));
            }
        } else {
            foreach ($array1 as $item) {
                $newArray1[] = md5("id:" . json_encode($item[$key]));
            }
            foreach ($array2 as $item) {
                $newArray2[] = md5("id:" . json_encode($item[$key]));
            }
        }
        $newArray = [];
        $diffArray = array_diff($newArray1, $newArray2);
        if (is_null($key)) {
            foreach ($diffArray as $diffItem) {
                foreach ($array1 as $item) {
                    if ($diffItem === md5("id:" . json_encode($item))) {
                        $newArray[] = $item;
                    }
                }
                foreach ($array2 as $item) {
                    if ($diffItem === md5("id:" . json_encode($item))) {
                        $newArray[] = $item;
                    }
                }
            }
        } else {
            foreach ($diffArray as $diffItem) {
                foreach ($array1 as $item) {
                    if ($diffItem === md5("id:" . json_encode($item[$key]))) {
                        $newArray[] = $item;
                    }
                }
                foreach ($array2 as $item) {
                    if ($diffItem === md5("id:" . json_encode($item[$key]))) {
                        $newArray[] = $item;
                    }
                }
            }
        }
        return array_values($newArray);
    }

    /**
     * 数组翻转
     * @param $list
     * @return array
     */
    public static function flip($list)
    {
        return array_reverse($list);
    }

    /**
     * 获取数组指定下标
     * @param $array
     * @param $key
     * @param $default
     * @param $config
     * @return mixed
     */
    public static function get($array, $key, $default = null, $config = [
        "decollator" => ".",
    ])
    {
        $item = $array;
        if (is_array($array)) {
            if (is_null($config["decollator"])) {
                $keyList = [$key];
            } else {
                $keyList = StrUtil::split($key, $config["decollator"]);
                if (count($keyList) == 0) {
                    return $default;
                } else if (count($keyList) == 1) {
                    $keyList = [$key];
                }
            }
            foreach ($keyList as $keyItem) {
                if (isset($item[$keyItem]) && is_array($item)) {
                    $item = $item[$keyItem];
                } else {
                    return $default;
                }
            }
            if (is_null($item)) {
                return $default;
            } else {
                return $item;
            }
        } else {
            return $default;
        }
    }

}